﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Collections.Specialized;

namespace AllTalk
{
    public partial class ChatPage : PhoneApplicationPage
    {
        internal ChatViewModel ChatViewModel { get; private set;}
        private ChatMessage _lastMessageSent;
        private bool _isDirty = false;

        public ChatPage()
        {
            InitializeComponent();
            ((INotifyCollectionChanged)this.ChatList.Items).CollectionChanged += new NotifyCollectionChangedEventHandler(ChatList_CollectionChanged);
            App.ConnectionManager.MessageSent += new EventHandler<MessageSentEventArgs>(ConnectionManager_MessageSent);
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            string email;
            if (NavigationContext.QueryString.TryGetValue("email", out email))
            {
                ChatViewModel chatViewModel;
                if (!App.ChatViewModels.TryGetValue(email, out chatViewModel))
                {
                    chatViewModel = new ChatViewModel(App.DataModel.Friends[email]);
                    App.ChatViewModels.Add(email, chatViewModel);
                }
                this.ChatViewModel = chatViewModel;
                this.DataContext = this.ChatViewModel;
                if (this.ChatList.Items.Count > 0)
                {
                    // Without beginInvoke it does not seem to do a refresh.
                    Dispatcher.BeginInvoke(new Action( 
                        () => this.ChatList.ScrollIntoView(this.ChatList.Items[this.ChatList.Items.Count - 1])));
                }
            }
        }

        protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
        {
            base.OnNavigatingFrom(e);
            if (_isDirty)
            {
                this.ChatViewModel.Save();
                _isDirty = false;
            }
        }

        private void TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            this.ApplicationBar.IsVisible = true;
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            this.ApplicationBar.IsVisible = false;
        }

        private void SendMessage_Click(object sender, EventArgs e)
        {
            if (this.ChatViewModel.Friend.Presence == Presence.Unavailable)
            {
                this.ChatViewModel.Status = String.Format("{0} is offline now.", this.ChatViewModel.Friend.Name);
                return;
            }
            
            ChatMessage message = new ChatMessage()
            {
                Message = this.MessageTextBox.Text,
                Sender = App.DataModel.CurrentJid,
                Recepient = this.ChatViewModel.Friend.ActiveJid,
                Timestamp = DateTime.Now
            };

            _lastMessageSent = message;
            App.ConnectionManager.SendMessageAsync(message);
            this.ChatViewModel.Status = "Sending...";
        }

        void ChatList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                this.ChatList.ScrollIntoView(e.NewItems[0]);
            }
            _isDirty = true;
        }

        private void MessageTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!String.IsNullOrEmpty(this.MessageTextBox.Text) && this.SendMessage != null)
            {
                this.SendMessage.IsEnabled = true;
            }
        }

        private void ConnectionManager_MessageSent(object sender, MessageSentEventArgs e)
        {
            if (e.Error != null)
            {
                this.ChatViewModel.Status = String.Format("Error: {0}", e.Error.Message);
            }
            else if (e.Message == _lastMessageSent)
            {
                this.ChatViewModel.ChatMessageViewModels.Add(new ChatMessageViewModel(_lastMessageSent));
                this.ChatList.Focus();
                this.MessageTextBox.Text = String.Empty;
                this.ChatViewModel.Status = String.Empty;
            }
        }
    }
}